using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Box2D.XNA;
using Animator;
namespace TurbaconPhone
{
    public class GameplayState : State
    {
        #region Fields
        public static List<GameObject> gObjects = new List<GameObject>();
        public CharacterTeam lastTeam;
        public Wall leftWall, rightWall;
        public Character curChar = null;
        //public Ball theBall;
        //public List<Character> Characters;
        GameplayHUD HUD;

        bool tapped;
        float doubleTapTimer;
        float doubleTapTime;

        Rectangle overlay;
        Rectangle reflexIndicator;
        float rIAngle;
        Texture2D rITex;
        float reflexTime = 1f;
        float reflexTimer;
        bool paused =false;
        SoundEffect goalSound;
        #endregion

        #region Constructor
        public GameplayState()
        {
            goalSound = TurBacon.Content.GetSound("goal1");
            TurBacon.GameInfo.Characters = new List<Character>();
            Vector2 size = new Vector2(800, 480);
            overlay = new Rectangle(0,0,(int)size.X, (int)size.Y);
            CreateBorder(new Vector2(), new Vector2(size.X, 0));
            leftWall=new Wall(new Vector2(), new Vector2(0, size.Y));
            rightWall=new Wall(new Vector2(size.X, 0), size);
            CreateBorder(new Vector2(0, size.Y), size);
            TurBacon.GameInfo.theBall = new Ball("Ball", size / 2, this);
            HUD = new GameplayHUD(size, leftWall, rightWall);
            reflexIndicator = new Rectangle();
            rITex = TurBacon.Content.GetTexture("slice");
            #region RedTeam
            CharDef def = new CharDef("Data/red.zmx");
            Character guyF = new Character(new Vector2(300, 100), def, PlayerType.forward, CharacterTeam.Red, Character.CharDir.Right);
            def = new CharDef("Data/red.zmx");
            Character guyM = new Character(new Vector2(200, 150), def, PlayerType.mid, CharacterTeam.Red, Character.CharDir.Right);
            def = new CharDef("Data/red.zmx");
            Character guyD = new Character(new Vector2(100, 100), def, PlayerType.defence, CharacterTeam.Red, Character.CharDir.Right);
            TurBacon.GameInfo.Characters.Add(guyF);
            TurBacon.GameInfo.Characters.Add(guyM);
            TurBacon.GameInfo.Characters.Add(guyD);
            #endregion

            #region BlueTeam
            def = new CharDef("Data/blue.zmx");
            //guy = new Character(new Vector2(400, 100), def);
            guyF = new Character(new Vector2(500, 300), def, PlayerType.forward, CharacterTeam.Blue, Character.CharDir.Left);
            //guyF.Speed = 100;
            def = new CharDef("Data/blue.zmx");
            guyM = new Character(new Vector2(600, 200), def, PlayerType.mid, CharacterTeam.Blue, Character.CharDir.Left);
            //guyM.Speed = 100;
            def = new CharDef("Data/blue.zmx");
            guyD = new Character(new Vector2(700, 240), def, PlayerType.defence, CharacterTeam.Blue, Character.CharDir.Left);
            //guyD.Speed = 100;
            TurBacon.GameInfo.Characters.Add(guyF);
            TurBacon.GameInfo.Characters.Add(guyM);
            TurBacon.GameInfo.Characters.Add(guyD);
            #endregion
            //   guy.SetAnim("run");
            //Characters.Add(guy);
        }
        #endregion

        #region Update and Draw
        public override void Update(GameTime gametime)
        {
            base.Update(gametime);
            if (paused)
            {
                if (reflexTimer > 0)
                {
                    reflexTimer -= (float)gametime.ElapsedGameTime.TotalSeconds;
                    reflexIndicator.X += (int)(Math.Cos((float)rIAngle) * 2);
                    reflexIndicator.Y -= (int)(Math.Sin((float)rIAngle) * 2);
                }
                else paused = false;
            }
            else
            {
                Physics.Advance((float)gametime.ElapsedGameTime.TotalSeconds);
                for (int i = 0; i < gObjects.Count; i++)
                {
                    gObjects[i].Update(gametime);
                }
            }
            HUD.Update(gametime);

            //if (DragOrigin.HasValue)
            //{
            //    movePlayerCheckTimer += gametime.ElapsedGameTime;
            //    if (movePlayerCheckTimer >= movePlayerCheckInterval)
            //    {
            //        DragOrigin = null;
            //    }
            //}


            if (leftWall.Health <= 0)
            {
                TurBacon.GameInfo.blueScore++;
                leftWall.Health = rightWall.Health = 1000;
                HUD.goal(CharacterTeam.Blue);
                goalSound.Play();
            }
            if (rightWall.Health <= 0)
            {
                TurBacon.GameInfo.redScore++;
                rightWall.Health = leftWall.Health = 1000;
                HUD.goal(CharacterTeam.Red);
                goalSound.Play();
            }

            if (TurBacon.GameInfo.redScore >= GameInfo.MAX_SCORE || TurBacon.GameInfo.blueScore >= GameInfo.MAX_SCORE)
            {
                if (TurBacon.GameInfo.redScore >= GameInfo.MAX_SCORE)
                {
                    TurBacon.GameInfo.WinningTeam = CharacterTeam.Red;
                    TurBacon.GameInfo.gameOver = true;
                }
                else
                {
                    TurBacon.GameInfo.WinningTeam = CharacterTeam.Blue;
                    TurBacon.GameInfo.gameOver = true;
                }
                TurBacon.StateManager.Push(new EndGameState());
            }

            
        }


        public override void Draw(SpriteBatch spriteBatch)
        {
            Graphics.Draw();
            if (paused)
            {
                Vector4 color = new Vector4();
                if (lastTeam == CharacterTeam.Red)
                    color.X = 1;
                else color.Z = 1;
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
                spriteBatch.Draw(TurBacon.Content.GetTexture("black"), overlay, new Color(1f, 1f, 1f, 0.7f));
                spriteBatch.Draw(rITex, reflexIndicator, null, new Color(color * reflexTimer), rIAngle, new Vector2(0, rITex.Height / 2), SpriteEffects.None, 0);
                spriteBatch.End();
            }
            HUD.Draw(spriteBatch);
        }
        #endregion

        private Body CreateBorder(Vector2 v1, Vector2 v2)
        {
            //create body
            BodyDef def = new BodyDef();
            Body border = Physics.World.CreateBody(def);
            //create shape
            PolygonShape shape = new PolygonShape();
            shape.SetAsEdge(v1 / Physics.WorldScale, v2 / Physics.WorldScale);
            //merge
            border.CreateFixture(shape, 0);
            border.SetUserData(null);
            return border;
        }

        

        #region State Methods
        public override void EnterState()
        {
            TurBacon.GameInfo.gameOver = false;
            TurBacon.GameInfo.blueScore = TurBacon.GameInfo.redScore = 0;
            leftWall.Health = rightWall.Health = 1000;
            EnabledGestures =
                    GestureType.Flick | 
                     // GestureType.DoubleTap | 
               // GestureType.FreeDrag |
                GestureType.Tap;// |
                //GestureType.DragComplete;
            base.EnterState();
        }
        //public override void HandleFreeDrag(GestureSample gesture)
        //{
        //    //if (curObj == null)
        //    //   curObj = new Ball("slice", gesture.Position);
        //    //if (curPlayer == null)
        //    //{
        //        foreach (Player player in Players)
        //            if (player.Contains(gesture.Position))
        //                curPlayer = player;
            
        //        movePlayerCheckTimer = TimeSpan.Zero;
        //    //}
        //    //else
        //    //{
        //       // Vector2 dir = gesture.Position - curPlayer.Pos;
        //       //// if (dir.Length() > 10)
        //       //// {
        //       //     curPlayer.Move(dir);
        //       //     movePlayerCheckTimer = TimeSpan.Zero;
        //       // }
        //        //curPlayer = null;
        //   // }
        //    DragToPosition = gesture.Position;
        //    base.HandleFreeDrag(gesture);
        //}
        public override void HandleTap(GestureSample gesture)
        {
            foreach (Character character in TurBacon.GameInfo.Characters)
                if (character.Contains(gesture.Position))
                {
                    if (curChar == character)
                    {
                        if (curChar.AbilityTimer <= 0)
                        {
                            curChar.AbilityActivated = true;
                        }
                       // curChar.TrailColor = Color.Red;
                        return;
                    }
                    else
                    {
                        if (curChar != null)
                        {
                            curChar.HasTrail = false;
                            curChar.Speed = Character.NormalSpeed;
                        }
                        curChar = character;
                        curChar.Speed = Character.SelectedSpeed;
                        curChar.HasTrail = true;
                        return;
                    }
                }

            if (curChar != null)
            {
                if (curChar.AbilityActivated && curChar.playerType == PlayerType.defence)
                {
                    curChar.TeleportAbility(gesture.Position);
                   
                }
                curChar.Move(gesture.Position);
            }

            //else
            //{
            //    foreach (Character character in Characters)
            //        if (character.Contains(gesture.Position))
            //        {
            //            if (curChar == character)
            //            {
            //                curChar = null;
            //            }
            //            else
            //            {
            //                curChar = character;
            //            }
            //        }
            //}

            base.HandleTap(gesture);
        }
        //public override void HandleHold(GestureSample gesture)
        //{
        //    if (curPlayer == null)
        //    {
        //        foreach (Player player in Players)
        //            if (player.Contains(gesture.Position))
        //                curPlayer = player;
        //    }
        //    else
        //    {
        //        curPlayer.Move(gesture.Position-curPlayer.Pos);
        //        //curPlayer = null;
        //    }
        //    base.HandleHold(gesture);
        //}
        //public override void HandleDragComplete(GestureSample gesture)
        //{
        //    if (curPlayer == null) return;
        //    Vector2 dir = DragToPosition - curPlayer.Pos;
        //    curPlayer.Move(dir);
        //    //DragToPosition = null;
        //    curPlayer = null;
        //    movePlayerCheckTimer = TimeSpan.Zero;
        //    base.HandleDragComplete(gesture);
        //}
        //public override void HandleDoubleTap(GestureSample gesture)
        //{
        //    if (curChar == null) return;

        //    curChar.AbilityActivated = true;

        //    base.HandleDoubleTap(gesture);
        //}

        public override void HandleFlick(GestureSample gesture)
        {
            if (curChar != null)
            {
                curChar.Stop();
                curChar.Kick(gesture.Delta);

                if ((TurBacon.GameInfo.theBall.Pos - curChar.Pos).Length() <= TurBacon.kickLength)
                {
                    if (!curChar.AbilityActivated)
                    {
                        TurBacon.GameInfo.theBall.KickBall(gesture.Delta, curChar);
                    }

                    else
                    {

                        TurBacon.GameInfo.theBall.SpecialKick(gesture.Delta, curChar);
                    }
                
                    
                    
                }
            }

            //if (curChar != null)
            //{
            //    curChar.Move(gesture.Delta);
            //    //curChar = null;
            //}
            ///*if (curObj != null)
            //{
            //    curObj.Vel = gesture.Delta;
            //    curObj = null;
            //}*/
            //base.HandleFlick(gesture);
        }
        #endregion

        public void ReflexTime(Vector2 v, Character player)
        {
            paused = true;
            reflexTimer = reflexTime;
            //Vector2 v = gesture.Delta;
            v.Normalize();
            v *= 500;
            Reflex(player.Pos, player.Pos + v);
            lastTeam=player.Team;
        }

        public void Reflex(Vector2 origin, Vector2 target)
        {
            reflexIndicator = new Rectangle((int)origin.X, (int)origin.Y, (int)(target - origin).Length(), (int)rITex.Height*2);
            Vector2 temp = Vector2.Clamp(target, new Vector2(), new Vector2(800, 480));
            temp = temp - target;
            reflexIndicator.X += (int)temp.X;
            reflexIndicator.Y += (int)temp.Y;
            rIAngle = (float)Math.Atan2(target.Y - origin.Y, target.X - origin.X);
        }

       

    }
}
